using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
public class SerializedDictionary<TKey, TValue> : ISerializationCallbackReceiver, IDictionary<TKey, TValue>
{
    // 用于序列化存储的列表
    [SerializeField]
    private List<TKey> keys = new List<TKey>();
    [SerializeField]
    private List<TValue> values = new List<TValue>();

    // 运行时使用的实际字典，提高访问效率
    private Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();

    #region ISerializationCallbackReceiver Implementation
    /// <summary>
    /// 序列化前调用：将字典数据转换为Unity可序列化的List形式
    /// </summary>
    public void OnBeforeSerialize()
    {
        keys.Clear();
        values.Clear();
        foreach (var kvp in dictionary)
        {
            keys.Add(kvp.Key);
            values.Add(kvp.Value);
        }
    }

    /// <summary>
    /// 反序列化后调用：从List数据重建字典
    /// </summary>
    public void OnAfterDeserialize()
    {
        dictionary.Clear();
        for (int i = 0; i < Mathf.Min(keys.Count, values.Count); i++)
        {
            // 避免重复键可能导致的问题[2](@ref)
            if (!dictionary.ContainsKey(keys[i]))
            {
                dictionary.Add(keys[i], values[i]);
            }
            else
            {
                Debug.LogWarning($"发现重复键: {keys[i]}，将跳过。");
            }
        }
    }
    #endregion

    #region IDictionary<TKey, TValue> Implementation
    public TValue this[TKey key]
    {
        get => dictionary[key];
        set => dictionary[key] = value;
    }

    public ICollection<TKey> Keys => dictionary.Keys;
    public ICollection<TValue> Values => dictionary.Values;
    public int Count => dictionary.Count;
    public bool IsReadOnly => false;
    public void Add(TKey key, TValue value) => dictionary.Add(key, value);
    public void Add(KeyValuePair<TKey, TValue> item) => dictionary.Add(item.Key, item.Value);
    public bool Remove(TKey key) => dictionary.Remove(key);
    public bool Remove(KeyValuePair<TKey, TValue> item) => dictionary.Remove(item.Key);
    public void Clear() => dictionary.Clear();
    public bool ContainsKey(TKey key) => dictionary.ContainsKey(key);
    public bool TryGetValue(TKey key, out TValue value) => dictionary.TryGetValue(key, out value);
    public bool Contains(KeyValuePair<TKey, TValue> item) => dictionary.ContainsKey(item.Key) && EqualityComparer<TValue>.Default.Equals(dictionary[item.Key], item.Value);
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        if (array == null) throw new ArgumentNullException(nameof(array));
        if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
        if (array.Length - arrayIndex < Count) throw new ArgumentException("目标数组空间不足");

        int i = 0;
        foreach (var kvp in dictionary)
        {
            array[arrayIndex + i] = kvp;
            i++;
        }
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => dictionary.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => dictionary.GetEnumerator();
    #endregion
}